<template>
<div>
  <el-radio style="padding: 0 0 10px 0" v-for="(item,index) in ccshowinfo.priceRange" :key="index" v-model="cclass" :label="index" class="pricemark">
    <span class="price">{{item.price}}</span>
    <span class="mark" :style="{backgroundColor: pricemarkcolor(item.class)}"></span>
  </el-radio>
  <div class="seatmap">
     <div
       v-for="seat in hallInfo.hallSeatMap"
       :key="seat.id"
       :class= "[ seat.isSeat ? 'seat' : 'notseat' ]"
       :style="{width:seatSize,height:seatSize}"
       @click='seatClick(seat)'
       @dblclick='selectrow(seat)'
       >
         <div class="icon" :ref="`seat${seat.id}`"></div>
     </div>
  </div>
</div>
</template>

<script>
let pm = {}
pm.id = []

export default {
  name: 'addshowseatmap',
  data () {
    return {
      // 价格图
      pricemap: [],
      // 价格座位图等级颜色数组
      pricecolor: ['#8fc460', '#0f7018', '#0d738f', '#54c0f6', '#e1c63f', '#ec6c3a'],
      // 价格座位图等级颜色数组
      pricecolorarr: ['#ec6c3a', '#e1c63f', '#54c0f6', '#0d738f', '#0f7018', '#8fc460'],
      // 保存上一次currentclass的值
      oldclass: 0,
      // 当前选中的等级
      cclass: 0,
      // 需要一个定时器来区分单击和双击
      timer: null,
      // 当前演出的信息
      // 把showinfo复制给cshowinfo并且，修改这个cshowinfo的信息，在caneditshowinfo切换的时候重新传入给displayshowinfo对话框
      ccshowinfo: {}
    }
  },
  props: {
    // 当前组件用于编辑剧目信息状态
    caneditshowinfo: {
      type: Boolean,
      default: false
    },
    // 当前组件用于添加剧目信息状态
    canaddshowinfo: {
      type: Boolean,
      default: false
    },
    // 传过来的演出厅数据
    hallInfo: {
      type: Object,
      default () {
        return {}
      }
    },
    // 当前座位的大小
    seatSize: {
      type: String,
      default: ''
    },
    // 传过来的价格区间
    price: {
      type: Array,
      default () {
        return []
      }
    },
    // 当前剧目信息
    showinfo: {
      type: Object,
      default () {
        return {}
      }
    }
  },
  // 通过watch来监听currentclass的变化，并且保存原来的值
  watch: {
    // 监听开关的数值变化
    caneditshowinfo () {
      if (this.caneditshowinfo === true) {
        this.getcolor()
        console.log('change caneditshowinfo')
      }
      if (this.caneditshowinfo === false) {
        console.log('把当前ccshowinfo的数据传给父组件')
        this.$emit('changeshowinfo', this.ccshowinfo)
      }
    },
    // 监听showinfo.pricemap
    changemap (n, o) {
      this.ccshowinfo = this.showinfo
      // 当这个pricemap发生变化的时候，需要把显示的图片一起更改
      // 这里关闭对话框的时候会出现undefined的情况，那么这里需要判断下
      if (typeof this.showinfo.pricemap !== 'undefined' && this.caneditshowinfo === true) {
        console.log('价格图数组变化了')
        console.log(n, o)
        if (o !== 'undefined' && n !== 'undefined') {
        // 这个是编辑页面的时候，new价格和old的价格数据都存在的情况下，就代表的是要重新渲染颜色
        // 清除所有的颜色
          this.clearallcolor()
          // 重新填充颜色
          this.getcolor()
        }
      }
    },
    // 在添加剧目的情况下需要监听价格数据的变化
    changepricerange () {
      if (this.canaddshowinfo === true) {
        console.log(this.showinfo.priceRange)
      }
    }
  },
  computed: {
    // 通过价格等级计算需要添加的颜色
    pricemarkcolor (index) {
      return function (index) {
        // console.log(this.pricecolorarr[Math.abs(index - this.pricearr.length + 1)], Math.abs(index - this.pricearr.length + 1))
        return this.pricecolorarr[Math.abs(index - this.ccshowinfo.priceRange.length + 1)]
      }
    },
    // 通过计算属性和watch结合起来监听pricemap的变化
    changemap () {
      return this.showinfo.pricemap
    },
    // 监听pricerange
    changepricerange () {
      return this.showinfo.priceRange
    }
  },
  methods: {
    // 去重程序 把arr内前后数据对比，把相同的通过splice截取掉
    distinct (arr) {
      for (var i = 0; i < arr.length; i++) {
        for (var j = i + 1; j < arr.length; j++) {
          if (arr[i] === arr[j]) {
            // 第一个等同于第二个，splice方法删除第二个
            arr.splice(j, 1)
            j--
          }
        }
      }
    },
    // 座位单击 选择一个座位的价格等级
    seatClick (seat) {
      // 单击的时候只需要把当前座位的id放入对应价格图中即可
      // 有2种情况，这个座位之前已经设定过价格/这个座位没有设定过价格
      // 情况1，通过在pricemap中寻找这个座位id是否存在
      // oldclass是这个被选中的作为原来的价格等级 seatindex是这个座位的位置
      // classindex是找到这个座位的时候，这个座位位于pricemap中的下标
      // hasprice是标识符，表示该座位之前已经有价格设定了，需要重设
      clearTimeout(this.timer)
      // 这里使用一个定时器来准确区分单击和双击
      this.timer = setTimeout(() => {
        if (seat.isSeat === true) {
          let newcolor = this.ccshowinfo.priceRange.length - this.cclass - 1
          let seatindex
          let newclass
          let hasprice
          this.ccshowinfo.pricemap.forEach((item, index) => {
            // item被循环遍历
            let has = item.id.indexOf(seat.id)
            // 如果该id存在的情况，这个座位之前价格等级和位置给存起来
            if (has !== -1) {
              seatindex = has
              newclass = index
              hasprice = true
            }
          })
          if (hasprice) {
          // 如果存在的话，还要在原来的数组里面删掉这个值
            console.log(`${seat.id}这个座位存在于pricemap`)
            console.log(`${seat.id}这个座位的原来的下标是${newclass}并且位于${seatindex}`)
            // 因为class和单选框里面对应的class是反过来的，这里要处理下数据
            let newcurrentclass = this.ccshowinfo.priceRange.length - 1 - newclass
            this.ccshowinfo.pricemap[newcurrentclass].id.splice(seatindex, 1)
            // 还要把这个值添加到新等级数组中
            // 如果这个现有的等级之前存在了 就直接添加，如果不存在还要新建个对象推入pricemap中
            // 查找currentclass在pricemap中的下标
            let hasclass = this.ccshowinfo.pricemap.findIndex(item => {
              return item.class === this.cclass
            })
            if (hasclass === -1) {
              // currentclass在price不存在的情况
              pm = {}
              pm.id = []
              pm.class = this.cclass
              pm.classprice = this.price[this.cclass]
              pm.id.push(seat.id)
              this.ccshowinfo.pricemap.push(pm)
            } else {
            // 此时hasclass就是这个数组中的下标
            // 推入数组中
              this.ccshowinfo.pricemap[hasclass].id.push(seat.id)
            }
            this.$refs[`seat${seat.id}`][0].style.backgroundColor = this.pricecolorarr[newcolor]
          } else {
            // 这个座位在pricemap中是不存在的情况
            // 查找currentclass在pricemap中的下标
            let hasclass = this.ccshowinfo.pricemap.findIndex(item => {
              return item.class === this.cclass
            })
            if (hasclass === -1) {
              // currentclass在price不存在的情况
              pm = {}
              pm.id = []
              pm.class = this.cclass
              pm.classprice = this.price[this.cclass]
              pm.id.push(seat.id)
              this.ccshowinfo.pricemap.push(pm)
            } else {
              // 此时hasclass就是这个数组中的下标
              this.ccshowinfo.pricemap[hasclass].id.push(seat.id)
            }
            // 之后直接添加颜色
            this.$refs[`seat${seat.id}`][0].style.backgroundColor = this.pricecolorarr[newcolor]
          }
          console.log(`单击座位${seat.id}`)
        }
      }, 300)
    },
    // 座位双击 选择整行的价格等级
    selectrow (seat) {
      // 如果在单击定时器还没完成的时候，双击了，那么就要清除定时器，这里设置可以很好地区分单双击
      if (seat.isSeat === true) {
        clearTimeout(this.timer)
        let selectedrow = []
        pm = {}
        pm.id = []
        let id = seat.id
        let haspriceclass = false
        for (let a of this.ccshowinfo.pricemap) {
          for (let b of a.id) {
            if (b === seat.id) {
              haspriceclass = true
              // 保存下原来的座位等级
              this.oldclass = a.class
              console.log(`这个被点击的座位原来的价格等级是${a.class}`)
              break
            }
          }
        }
        // 通过拆分这个id来确定这个点击的座位在这个seatmap上面的位置
        // 获取被双击点中的位置位于第几行/第几列
        let row = parseInt(id.split('-')[0])
        let col = parseInt(id.split('-')[1])
        // 将座位id分割出来，然后计算成当前列表中位于第几个
        let num = row * this.hallInfo.hallWidth + col
        console.log(`双击座位是第${num}个座位位于${row}行${col}列`)
        // 获得索引值之后，如果索引值为0 就只要向后查询，如果不为0就前后都要查询，查询到这个座位为false或者行数切换了
        for (let i = num; i >= 0; i--) {
          let currentrow = parseInt(this.hallInfo.hallSeatMap[i].id.split('-')[0])
          if (this.hallInfo.hallSeatMap[i].isSeat === true && currentrow === row) {
            selectedrow.push(this.hallInfo.hallSeatMap[i].id)
          }
          if (this.hallInfo.hallSeatMap[i].isSeat === false || currentrow !== row) break
        }
        // 当前行结束的位置
        let end = this.hallInfo.hallWidth * (row + 1)
        for (let i = num; i <= end; i++) {
          let currentrow = parseInt(this.hallInfo.hallSeatMap[i].id.split('-')[0])
          if (this.hallInfo.hallSeatMap[i].isSeat === true && currentrow === row) {
            selectedrow.push(this.hallInfo.hallSeatMap[i].id)
          }
          if (this.hallInfo.hallSeatMap[i].isSeat === false || currentrow !== row) break
        }
        // 对选中数据进行排序
        selectedrow.sort((a, b) => { return a - b })
        // 先查询这个等级的数据是否存在
        let priceindex = this.ccshowinfo.pricemap.findIndex(item => {
          return item.class === this.cclass
        })
        if (priceindex === -1) {
        // 如果不存在这个等级就添加上去
        // console.log('等级不存在')
          pm.class = this.cclass
          pm.classprice = this.price[this.cclass]
          pm.id = selectedrow.sort()
          this.ccshowinfo.pricemap.push(pm)
          // 这里还要根据class进行一次排序
          this.ccshowinfo.pricemap.sort((value1, value2) => {
            let val1 = value1.class
            let val2 = value2.class
            return val1 - val2
          })
          // 更新当前currentclass在pricemap中的位置
          priceindex = this.ccshowinfo.pricemap.findIndex(item => {
            return item.class === this.cclass
          })
        } else {
        // console.log('等级存在')
          this.ccshowinfo.pricemap[priceindex].id.push(...selectedrow)
          this.ccshowinfo.pricemap[priceindex].id.sort()
          // 考虑到之前单击有可能已经选择了这一排的某个座位，会重复推入座位需要去重
          this.distinct(this.ccshowinfo.pricemap[priceindex].id)
        }
        // 当推送结束之后需要把这个选中的座位全部添加上颜色 refs通过模板字符串获取对应id
        for (let i = 0; i < selectedrow.length; i++) {
          this.$refs[`seat${selectedrow[i]}`][0].style.backgroundColor = this.pricecolorarr[this.ccshowinfo.priceRange.length - this.cclass - 1]
        }
        // 处理pricemap对象数组
        // 分为2种情况，这一行的座位已经有自己对应的价格等级了或者没有
        // 这里的haspriceclass在这个数据被推入pricemap前判定，可以保证数据不出错
        if (haspriceclass) {
        // 情况一： 这个座位之前已经有了价格等级，那么要在原来的pricemap中删除他，并把它放在新的价格等级里面
          console.log(`原来的价格等级是${this.oldclass},这个选中的一行长度为${selectedrow.length}`)
          // 通过遍历循环去除重复数据
          for (let i = 0; i < this.ccshowinfo.pricemap[this.oldclass].id.length; i++) {
            for (let j = 0; j < selectedrow.length; j++) {
              if (this.ccshowinfo.pricemap[this.oldclass].id[i] === selectedrow[j]) {
              // console.log('删除座位')
                this.ccshowinfo.pricemap[this.oldclass].id.splice(i, 1)
                j--
              }
            }
          }
        // console.log(this.ccshowinfo.pricemap)
        } else {
        // 情况二： 没有价格等级，直接推入并且去重
        // 考虑到之前单击有可能已经选择了这一排的某个座位，会重复推入座位
          this.distinct(this.ccshowinfo.pricemap[priceindex].id)
          console.log(this.ccshowinfo.pricemap)
        }
      }
    },
    // 在编辑剧目信息的时候需要通过传入的pricemap来给整个seatmap填色
    getcolor () {
      // 通过price对象数组来确定价格数组
      console.log('get color')
      let pricearr = []
      this.price.forEach(item => {
        pricearr.push(item.price)
      })
      pricearr.sort((a, b) => { return b - a })
      // console.log(pricearr)
      // console.log(this.ccshowinfo.pricemap)
      this.ccshowinfo.pricemap.forEach(item => {
        // console.log(item)
        // 先确定好当前价位是价位的哪个等级
        let priceclass = pricearr.indexOf(item.price)
        // 确定对应等级的颜色
        // console.log(priceclass)
        let color = this.pricecolorarr[priceclass]
        // console.log(priceclass, color)
        // 开始循环添加颜色
        item.id.forEach(y => {
          // console.log('循环')
          this.$nextTick(() => {
            this.$refs[`seat${y}`][0].style.backgroundColor = color
          })
        })
      })
    },
    // 用于清除所有颜色
    clearallcolor () {
      console.log('clear color')
      this.hallInfo.hallSeatMap.forEach(item => {
        this.$nextTick(() => {
          this.$refs[`seat${item.id}`][0].style.backgroundColor = 'pink'
        })
      })
    }
  },
  mounted () {
    this.ccshowinfo = this.showinfo
    // this.pricemap = this.cshowinfo.pricemap
    // console.log(this.cshowinfo.pricemap)
  }
}
</script>

<style lang="stylus" scoped>
.pricemark
    height 40px
    line-height 40px
    padding-right 30px
    .price
      height 20px
      line-height 20px
      padding 8px 12px
      font-size 12px
    .mark
      display inline-block
      width 20px
      height 20px
.seatmap
  font-size 0
  box-sizing border-box
  .seat
    display inline-block
    padding 2px
    .icon
      width 100%
      height 100%
      background-color pink
  .notseat
    opacity 0.5
    display inline-block
</style>
